package com.ytjj.qmyx.mall.service.thirdpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.Payment;
import com.ytjj.common.exception.GlobalExceptionHandler;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.DateTimeUtil;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.common.utils.IPUtil;
import com.ytjj.common.utils.TokenUtil;
import com.ytjj.common.utils.feishu.FeiShuUtil;
import com.ytjj.qmyx.mall.config.SupplyApiConfig;
import com.ytjj.qmyx.mall.constants.IsPayConstant;
import com.ytjj.qmyx.mall.enums.OrderPaySource;
import com.ytjj.qmyx.mall.enums.OrderPayTypeEnums;
import com.ytjj.qmyx.mall.enums.OrderStatusEnums;
import com.ytjj.qmyx.mall.enums.PayPayTypeEnums;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.mall.model.dto.WxPayDto;
import com.ytjj.qmyx.mall.model.request.UpdateOrderStatusRequest;
import com.ytjj.qmyx.mall.service.OrdersService;
import com.ytjj.qmyx.mall.service.ProductService;
import com.ytjj.qmyx.mall.service.WxService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("APP-HFTX")
@Slf4j
public class AdapayServiceImpl implements WxService<WxPayDto> {


    private static final String SUCCESS = "succeeded";
    private static final String FAILED = "failed";
    private static final String PENDING = "pending";

    @Resource
    private OrdersDao ordersDao;

    @Resource
    private OrdersPayMapper ordersPayMapper;
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private OrdersInfoMapper ordersInfoMapper;

    @Resource
    private RedisService redisService;
    @Resource
    private ProductService productService;

    @Resource
    private OrdersService ordersService;

    @Resource
    private ReturnGoodsDao returnGoodsDao;
    @Resource
    private SupplyApiConfig supplyApiConfig;

    @Value("${quanmingyanxuan.adapay.NOTIFY_URL}")
    private String adapayNotifyUrl;

    @Override
    public Map<String, String> doUnifiedOrder(WxPayDto wxAppPayDto) throws Exception {

        Map<String,String> param = new HashMap<>();

        String ip;
        try {
            ip = IPUtil.getIpAddress(TokenUtil.getRequest());
        } catch (Exception e) {
            log.error("ip获取报错:",e);
            ip = "0.0.0.0";
        }
        try {
            Map<String, Object> paymentParams = new HashMap<String, Object>(10);
            paymentParams.put("app_id", "app_c76bf9ba-d40d-4e04-bad4-eae9a5e72472");
            paymentParams.put("order_no", wxAppPayDto.getResOrderNo());
            paymentParams.put("pay_channel", "alipay_qr");
            paymentParams.put("pay_amt", wxAppPayDto.getRealTotalMoney());
            paymentParams.put("goods_title", wxAppPayDto.getBody());
            paymentParams.put("goods_desc", wxAppPayDto.getBody());
            paymentParams.put("div_members", "");
            paymentParams.put("notify_url", adapayNotifyUrl);


            Map<String, Object> device_info = new HashMap<String, Object>(10);
            device_info.put("device_ip",ip);
            paymentParams.put("device_info",device_info);

            Map<String, Object> payment = Payment.create(paymentParams);
            log.info("汇付天下payment,{}", JSON.toJSONString(payment));
            String status = (String) payment.get("status");
            String id = (String) payment.get("id");
            if (SUCCESS.equals(status)){
                Map<String,String> expend = (Map<String,String>)payment.get("expend");
                param.put("redirectUrl",expend.get("qrcode_url"));
                param.put("transaction_id",id);
            }
            if (FAILED.equals(status)){
                String error_msg = (String) payment.get("error_msg");
                FeiShuUtil.sendMsg(String.format("汇付天下创建支付失败,%s",error_msg));
            }
        } catch (Exception e) {
            log.error("汇付天下创建支付失败,{}",e);
            throw new RuntimeException(e);
        }
        return param;
    }

    public void notifyAdapay(String data){
        updateOrderInfo(data);
    }

    public void updateOrderInfo(String data){
        Map<String,Object> map = JSON.parseObject(data, Map.class);
        String status = (String) map.get("status");
        String orderNo = (String) map.get("order_no");
        OrdersPay pay = ordersDao.queryOrdersPayByResOrderNo(orderNo);
        pay.setResText(data);
        if (SUCCESS.equals(status)){
            String serialNumber = (String) map.get("id");
            String orderAmount = (String) map.get("pay_amt");
            if (StringUtils.isNotBlank(orderNo)){
                if (null == pay || (pay.getPayType().byteValue() == PayPayTypeEnums.SUCCEED.getType())) {
                    return;
                }
                // 更新支付订单信息
                if (StringUtils.isNotBlank(orderAmount)) {
                    Integer totalFee = (new BigDecimal(orderAmount).multiply(new BigDecimal(100))).intValue();
                    pay.setTotalFee(totalFee);
                } else {
                    if (null != pay.getAmount()) {
                        BigDecimal big_total_fee = pay.getAmount().multiply(new BigDecimal(100));
                        pay.setTotalFee(big_total_fee.intValue());
                    }
                }
                pay.setPayTime(DateTimeUtil.getTime());
                pay.setPayType(PayPayTypeEnums.SUCCEED.getType());
                pay.setUpdateTime(new Date());
                pay.setTransactionId(serialNumber);
                ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);

                // 更新订单信息
                Orders orders = new Orders();
                orders.setPayType(OrderPayTypeEnums.online_pay.name());
                orders.setPaySource(OrderPaySource.alipay.name());
                orders.setIsPay(IsPayConstant.YES);
                orders.setOrderStatus(OrderStatusEnums.UNSHIPPED.getValue());
                orders.setPayTime(new Date());
                orders.setTradeNo(pay.getResOrderNo());
                OrdersExample example = new OrdersExample();
                example.createCriteria()
                        .andOrderNoEqualTo(pay.getOrderNo());
                ordersMapper.updateByExampleSelective(orders, example);
                // 获取订单信息
                Orders order = ordersDao.queryOrdersByOrderNo(pay.getOrderNo());

                // 获取订单明细
                OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
                ordersInfoExample.createCriteria().andOrderIdEqualTo(order.getId());
                List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
                ordersInfoList.stream()
                        .forEach(item -> {
                            String tokenUser = redisService.get(order.getH5Token());

                            // 修改订单详情状态
                            OrdersInfo ordersInfo = new OrdersInfo();
                            ordersInfo.setId(item.getId());
                            ordersInfo.setOrderinfoStatus(OrderStatusEnums.UNSHIPPED.getValue());
                            ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                            try {
                                // 商品 减库存 加销量 店家加销量
                                productService.sellAfter(item.getProductId(), item.getProductSpecId(), item.getProductSum(), item.getProductPrice(),
                                        item.getIsWalletPay(),tokenUser, item.getIsDirectbuy(), item.getActivityType(), item.getActivityMax(), order.getUserId());
                            } catch (Exception e) {
                                log.error(GlobalExceptionHandler.getExceptionToString(e));
                                log.error("减库存发生异常 订单id :{}", item.getId());
                            }

                        });
                //扣减库存
                try {
                    ordersService.subStock(order.getId());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if (FAILED.equals(status)){
            // 更新支付订单信息
            pay.setPayType(PayPayTypeEnums.FAIL.getType());
            pay.setUpdateTime(new Date());
            ordersPayMapper.updateByPrimaryKeyWithBLOBs(pay);
        }
    }

    public void notifyAdapayRefund(String data){
        Map<String,Object> map = JSON.parseObject(data, Map.class);
        String status = (String) map.get("status");
        String paymentId = (String) map.get("payment_order_no");
        if (SUCCESS.equals(status)){
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //修改订单相关状态
            updateAdminOrderInfo(paymentId);
            // 退款表状态更新
            ordersDao.updateOrderRefundStatusByTradeNo(2,paymentId,data);
        }
        if (FAILED.equals(status)){
            // 退款表状态更新
            ordersDao.updateOrderRefundStatusByTradeNo(3,paymentId,data);
        }
    }

    public void updateAdminOrderInfo(String trade_no){
        Integer orderInfoId = ordersDao.findOrderInfoIdByTradeNo(trade_no);
        log.info("trade_no:{},orderInfoId:{}",trade_no,orderInfoId);
        if (orderInfoId!=null){
            ReturnGoods returnGoodsInfo = ordersDao.selectReturnGoodsByWaitBackAmount(orderInfoId);
            log.info("ReturnGoods:{}",JSON.toJSONString(returnGoodsInfo));
            if (returnGoodsInfo!=null){
                // 同步退货管理中的退货状态
                returnGoodsDao.returnGoodsSuccess(returnGoodsInfo.getId());
                //交易关闭原因
                String closeRemarks = getCloseRemarks(returnGoodsInfo);

                //退款成功主子订单为已关闭
                OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(returnGoodsInfo.getOrdersInfoId());
                ordersDao.updateStatusByOid(returnGoodsInfo.getOrdersInfoId(), "4", closeRemarks);
                ordersDao.updateOrderStatusById(ordersInfo.getOrderId(),"4",returnGoodsInfo.getServiceNo());

                // 原路返回页中订单详情状态改为已关闭
                ordersDao.modifiedReturnRegister(returnGoodsInfo.getOrdersInfoId());

                //更新供应链订单状态  销售端调用 （当销售端退款后，需要修改订单状态）
                UpdateOrderStatusRequest updateOrderStatusRequest = new UpdateOrderStatusRequest();
                updateOrderStatusRequest.setChildOrderNo(ordersInfo.getChildOrderNo());
                updateOrderStatusRequest.setShopId(supplyApiConfig.getShopId());
                updateOrderStatusRequest.setOrderStatus(4);
                String json = JSON.toJSONString(updateOrderStatusRequest);
                HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/order/updateOrderStatus", json, supplyApiConfig.getHeadsMap());

                //更新供应链售后信息
                YxReturnGoods yxReturnGoodsRequest = new YxReturnGoods();
                yxReturnGoodsRequest.setServiceNo(returnGoodsInfo.getServiceNo());
                yxReturnGoodsRequest.setStatus(9);

                yxReturnGoodsRequest.setShopId(supplyApiConfig.getShopId());
                String json2 = JSON.toJSONString(yxReturnGoodsRequest);
                HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/returnGoods/updateReturnGoods", json2, supplyApiConfig.getHeadsMap());
            }
        }
    }

    public String getCloseRemarks(ReturnGoods returnGoodsInfo) {
        String closeRemarks = "";
        if (returnGoodsInfo.getAfterType() == 1) {
            closeRemarks = "订单已申请退款";
        } else if (returnGoodsInfo.getAfterType() == 2) {
            closeRemarks = "订单已申请退货退款";
        } else if (returnGoodsInfo.getAfterType() == 3) {
            closeRemarks = "订单已申请仅退款";
        }
        return closeRemarks;
    }





    @Override
    public Map<String, String> doUnifiedRechargeOrder(WxPayDto wxPayDto) throws Exception {
        return null;
    }

    @Override
    public Map<String, String> wxOrderQuery(String transactionId) throws Exception {
        Map<String, Object> response = Payment.query(transactionId);
        String data = JSON.toJSONString(response);
        log.info("汇付天下支付查询结果,{}",data);
        updateOrderInfo(data);
        return null;
    }

    @Override
    public Map<String, String> wxPhoneChargesQuery(String resOrderNo) throws Exception {
        return null;
    }

    @Override
    public Map refundOrders(String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee, String refundDesc) throws Exception {
        return null;
    }

    @Override
    public Map refundRecharge(String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee, String refundDesc) throws Exception {
        return null;
    }
}
